﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Pahan.McuFusion.Common;
using Pahan.McuFusion.Common.Serialization;
using Pahan.McuFusion.Spi;

namespace Pahan.McuFusion.Atmel.AVR
{
    [Serializable]
    public class AvrSpiProgrammerInfo : ProgrammerInfo
    {
        #region Overrides of BaseInfo

        public override string Name
        {
            get { return "AVR Bitbang SPI Programmer"; }
        }

        public override string Description
        {
            get { return "Algorithm Builder compatible AVR bitbang SPI programmer"; }
        }

        #endregion

        #region Overrides of ProgrammerInfo

        /// <summary>
        /// Gets the list of the supported microcontrollers.
        /// </summary>
        public override IList<DeviceInfo> SupportedMicrocontrollers
        {
            get
            {
                var reader = new JsonDeviceInfoListReader<AvrMcuInfo>();
                var dir = Path.GetDirectoryName(
                    Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
                var path = Path.Combine(dir, "Atmel.AVR.json");
                return reader.ReadList(path).Cast<DeviceInfo>().OrderBy(d => d.Model).ToList();
            }
        }

        /// <summary>
        /// Creates an instance of the programmer.
        /// </summary>
        /// <param name="mcu">Target microcontroller.</param>
        /// <param name="adapter">Target adapter.</param>
        /// <returns></returns>
        public override IProgrammer CreateProgrammer(DeviceInfo mcu, IHardwareAdapter adapter)
        {
            Assert.NotNull(mcu, "mcu");
            Assert.NotNull(adapter, "adapter");
            Assert.OfType<AvrMcuInfo>(mcu, "mcu");
            Assert.OfType<ISpiAdapter>(adapter, "adapter");
            return new AvrSpiProgrammer((AvrMcuInfo)mcu, this, (ISpiAdapter)adapter);
        }

        /// <summary>
        /// Checks whethes the specified hardware adapter is supported by the programmer.
        /// </summary>
        public override bool Supports(HardwareAdapterInfo hardwareAdapter)
        {
            return hardwareAdapter.Implements<ISpiAdapter>();
        }

        #endregion
    }
}
